package demo02ClassObj;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:咭咭熊
 * Date:2021 - 09 - 13
 * Time:9:46
 */

/***
 * 面向对象语言OOP的特征：封装、继承、多态
 * 二、 封装——使用private修饰类的成员属性，提供get和set的公共访问方法进行类的属性的操作；
 * 1。封装的本质——就是让【类的调用者】不必太多的了解【类的实现者】是如何实现类的妹纸哟啊直到如何使用类即可；
 *    封装的意义——让类的调用者对类学习和使用成本降本，从而降低了复杂程度；
 *
 * 2.private实现封装
 *  访问权限修饰符：private、public
 * （1）被public修饰的成员变量或者成员方法，，可以直接被类的调用者使用；
 * （2）被pri吧te修饰的成员变量或综合成员方法，不能被类的调用者使用；
 *
 * 3. （1）所有被private 所修饰的成员变量或者成员方法都只能在类内进行访问；
 *    （2）所有被private 所修饰的成员变量或者成员方法——在累哦爱要进行访问，需要提供公有的接
 *
 * 4.this代表什么？——this代表当前对象引用【在创建对象的第一步：为对象分配内存】
 *      当构造方法调用完成之后，才产生了对象；
 *
 * 5.构造方法——一种特殊的方法【区别于普通方法：没有返回值】，使用关键字new实例化新对象时会被自动调用，用于完成初始化操作：
 * （1）new执行过程：
 *      为对象分配内存空间；
 *      调用对象的构造方法；
 *
 * （2）面试问题：实例化一个对象需要几步？
 *      Student student= new Student();//实例化了一个对象
 *      答案：两步：
 *          第一步：为对象分配内存；
 *          第二步：调用合适的构造方法，说明构造方法不止一个，可能由多个；
 *          执行结束这两步骤，才完产生了了对象；
 *
 * （3）如果一个类没有写任何的构造方法那么编译器会为当前类生成【一个默认的不带有参数的构造方法】；
 *      只要我们自己写了其它的构造方法，那么编译器就不会再我们生昵称你一个不带有参数的构造方法了；
 *      构造方法可以发生重载；
 *
 * 6.重载
 * （1）方法名相同；
 * （2）参数列表不同【个数和类型】
 * （3）返回值不做要求
 *
 * 7.this关键字：表示当前对象的引用；
 * （1）this.属性——访问当前对象的属性；
 * （2）this.func()——调用当前对象的方法
 * （3）this()——调用当前对象的构造方法
 *
 * 8.代码块
 * （1）本地代码块  - {}：定义在方法内部的代码块
 * （2）静态代码块—— static{}
 * （3）实例代码块/构造代码块——{}
 * （4）同步代码块
 *
 * 9.
 *
 * 10.
 */
class Student{
/*    public String name;
    public int age;*/
    //private实现封装——在类外不能访问私有属性——需要提供get和set方法来进行操作属性
    private String name;
    private int age;
    private static  int count;

    //不带有参数的构造方法
    public Student(){
        //调用带有两个参数的构造方法，必须放在第一行，且只能存在于构造方法内部
        this("java",20);
        System.out.println("调用了不带有参数的构造方法。。。。");
    }

    //带有一个参数的构造方法
    public Student(String name1){
        this.name = name1;
        System.out.println("调用了带有一个String类型参数的构造方法。。。。");
    }
    //带有两个参数的构造方法
    public Student(String name2,int age2){
        this.name = name2;
        this.age = age2;
        System.out.println("调用了带有两个参数的构造方法。。。");
    }
    /***
     * 静态代码块
     */
    static{
        count = 10;
        System.out.println("静态代码块。。。。");
    }

    /***
     * 实例代码块
     */
    {
        this.age = 15;
        this.name = "wangwu";
        count = 999;
        System.out.println("实例代码块。。。");
    }

    /***
     * 约定：只要将类的属性或者方法设置为public，那么我们就默认其不会反生改变；
     * @return
     */

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    /***
     * 所有被private 所修饰的成员变量或者成员方法都只能在类内进行访问；
     * 所有被private 所修饰的成员变量或者成员方法——在累哦爱要进行访问，需要提供公有的接口
     * 私有方法func()只能在类内进行访问；
     */
    private void func(){
        System.out.println("func()");
    }
    //静态方法中不可以使用this关键字
    public void func2(){
        this.func();
    }
}
public class Encapsulation {
    /***
     * 执行顺序：静态代码块——实例代码块——构造方法
     * 即使创建了多个对象：静态代码块也只执行一次；
     * 如果都是静态的，才与执行顺序有关系；
     * 如果都是实例的，才与执行顺序有关系；
     * @param args
     */
    public static void main(String[] args) {
        Student stu1 = new Student();
        System.out.println("============");

        Student stu2 = new Student();
    }
    /***
     * 6.本地代码块
     * @param args
     */
    public static void main6(String[] args) {
        int a = 20;
        {
            //本地代码块——定义在方法内部的代码块
//            int a = 10;
            System.out.println(a);
        }
        System.out.println(a);
    }

    /***
     * 匿名对象的优点：简化代码
     */
    public static void function(Student stu) {
        function(new Student());

        Student student = new Student();
        function(stu);
    }
    /***
     * 4.匿名对象的缺点：只能使用一次
     * @param args
     */
    public static void main4(String[] args) {
        new Student().func2();;//匿名对象
        new Student().func2();

        Student student = new Student();
        student.func2();
        student.func2();
    }
    /***
     * 3.this();——调用构造方法
     * @param args
     */
    public static void main3(String[] args) {
        Student student = new Student();
        System.out.println(student);

    }
    /***
     * 2.实例化一个对象需要几步？
     * @param args
     */
    public static void main2(String[] args) {
        Student student = new Student();//分配内存；调用合适的构造方法
        System.out.println(student);
        System.out.println("=============");

        Student student1 = new Student("张三");
        System.out.println(student1);
        System.out.println("=============");

        Student student2 = new Student("李四",20);
        System.out.println(student2);
        System.out.println("=============");
    }
    /***
     * 1.访问属性以及方法
     */
    public static void main1(String[] args) {
        Student student = new Student();
        //在类外不能访问到私有属性
/*        student.getname = "zhangnsan";
        student.age = 10;*/
        student.setName("张三");
        student.setAge(20);

        student.func2();

    }
}
